<?php
// Identification token
// Token fields:
//    type:            1
//    timeout:         4
//    md5(uname + pwd_md5 + timeout + secret )
//    pwd_md5          4
//    uname:           uname_length + 1

if ( defined( "_PARA__TOKEN" ) )
    return;
define("_PARA__TOKEN", 1 );

class Token {

    public static $uname_len;
    public static $token_type;
    public static $secret;
    public static $timeout_time;


    static function parse( $token ) {
        $raw_token = base64_decode( $token );

        // return error if base64 has failed
        if(!$raw_token) 
            return array( 'status' => 'error', 'errcode' => 'BASE64' );

        // ridiculous php syntax for unpack makes things stupid
        $unpack_string =
            "ctype/" .
            "Ntimeout/" .
            "H32md5_check/" .
            "H32pwd_md5/" .
            "a*uname";

        $stuff = unpack( $unpack_string, $raw_token );

        // do integrity check
        $md5_check = md5($stuff['uname'] . $stuff['timeout'] . self::$secret );
        if($md5_check != $stuff['md5_check'])
            return array('status' => 'error', errcode => 'INTEGRITY');
           
        // do timeout check
        if(time() > $stuff['timeout']) {
            $stuff['status']  = 'error';
            $sfuff['errcode'] = 'TIMEOUT';
            return $stuff;
        }            

        // return on success
        $stuff['status'] = 'ok';
        return $stuff;
    }


    static function generate($uname, $pwd_md5, $timeout ) {

        $pack_string =
            "c" .
            "N" .
            "H32" .
            "H32" .
            "a*" ;

        $uname_safe = substr($uname, 0, self::$uname_len);

        $timeout   =  time() + self::$timeout_time;
        $raw_token = 
            pack(
                $pack_string,
                self::$token_type,
                $timeout,
                md5($uname . $timeout . self::$secret ),
                $pwd_md5 ,
                $uname_safe
                );

        return base64_encode( $raw_token );
    }

}

// intialize static vars. This seems to be the only way.

Token::$uname_len    = 51;
Token::$secret       = 'fisk';
Token::$timeout_time = 1800;
Token::$token_type   = 1;
?>